#include "List.h"

// initialize a list
void InitList(List *L) {
    L = (List *) malloc(sizeof(List));
    L->elem = (ElemType *) malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if (L->elem == NULL) {
        ErrorMessage("Memory allocation failed.");
        exit(OVERFLOW);
    }
    L->length = 0;
    L->size = LIST_INIT_SIZE;
    L->incrementsize = LIST_INCREMENT;
}

// find index of element in list
int LocateElem(List L, ElemType e) {
    int i = 0;
    ElemType *p = L.elem;
    while (i<L.length && *p++ != e)
        ++i;
    if (i <L.length)
        return i;
    else
        return INDEX_ERROR;
}

// get value of element by index
void GetElem(List L, int i, ElemType *e) {
    e = &(L.elem[i - 1]);
}

// insert one element in list
void ListInsert(List *L, int i, ElemType e) {
    if (i<1 || i>L->length + 1) {
        printf("%d\n", L->length);
        ErrorMessage("illegal value of i !!");
        exit(ERROR);
    }
    if (L->length >= L->size)
        increment(L);
    ElemType *q = &(L->elem[i-1]);  // location of element to be inserted
    ElemType *p;
    for (p=&(L->elem[L->length-1]); p>=q; --q)  //right shift elements behind e
        *(p+1) = *p;
    *q = e;  // insert e
    ++L->length;
}

// delete one element from list
void ListDelete(List *L, int i, ElemType *e) {
    if (i<1 || i> L->length) {
        ErrorMessage("illegal value of i !!");
        exit(ERROR);
    }
    ElemType *p = &(L->elem[i - 1]);
    e = p;
    ElemType *q = L->elem + L->length-1;
    for (++p; p<=q; ++p)
        *(p-1) = *p;
    -- L->length;
}

// destory a list
void DestoryList(List *L) {
    free(L->elem);
    L->length = 0;
    L->size = 0;
}

// increase size of list
void increment(List *L) {
    //ElemType a[];
    ElemType *a = (ElemType *) malloc((L->size + L->incrementsize) * sizeof(ElemType));
    if (a == NULL) {
        ErrorMessage("Memory allocation failed.");
        exit(OVERFLOW);
    }
    for (int i=0; i<L->length; i++)
        a[i] = L->elem[i];
    free(L->elem);
    L->elem = a;
    L->size += L->incrementsize;
}

void ErrorMessage(char *s) {
    printf("%s\n", s);
    exit(ERROR);
}
